package com.lagou.rpc.consumer;

import com.alibaba.fastjson.JSON;
import com.lagou.rpc.common.RpcRequest;
import com.lagou.rpc.common.RpcResponse;
import com.lagou.rpc.consumer.client.RpcClient;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.UUID;

@Aspect
@Component
public class RpcAdvice {

    private static final String POINT_CUT = "execution(public * com.lagou.rpc.api.IUserService.getById(int))";

    private static  int count = 0;// 存储请求次数，用于负载均衡
    private static int[] ports = {8888,8889,8890};//端口号

    @Pointcut(POINT_CUT)
    public void pointCut(){

    }

    @Around(value = POINT_CUT)
    public Object doAroundAdvice(ProceedingJoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Object o = null;
        RpcClient rpcClient = null;
        Object result = null;
        try {
            //1.封装Request对象
            RpcRequest rpcRequest = new RpcRequest();
            rpcRequest.setRequestId(UUID.randomUUID().toString());
            rpcRequest.setClassName(method.getDeclaringClass().getName());
            rpcRequest.setMethodName(method.getName());
            rpcRequest.setParameters(joinPoint.getArgs());
            rpcRequest.setParameterTypes(method.getParameterTypes());
            //2.创建RpcClient对象
            int port = ports[count++ % 3];
            rpcClient = new RpcClient("127.0.0.1", port);
            //3.发送消息调用远程方法
            o = rpcClient.sendMsg(JSON.toJSONString(rpcRequest));
            RpcResponse rpcResponse = JSON.parseObject(o.toString(), RpcResponse.class);
            if (rpcResponse.getError() != null) {
                throw new RuntimeException("远程调用发生异常，异常信息：" + rpcResponse.getError());
            }
            //4.返回响应结果
            result = rpcResponse.getResult();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            rpcClient.close();
        }
        return JSON.parseObject(result.toString(),method.getReturnType());
    }
}
